#include "register.hpp"

Register::Register(int address, int bank, int standard)
    : standard(standard), address(address), bank(bank)
{
    this->mutex = new QMutex(QMutex::Recursive);
    QMutexLocker(this->mutex);
    this->value = -1;
}


Register::~Register()
{
    delete this->mutex;
}


void Register::setBit(int bit)
{
    if (bit < 0 || bit > 7)
	return;

    int mask = pow(2, bit);
    int value = this->getValue() | mask;

    this->setValue(value);
}


void Register::clearBit(int bit)
{
    if (bit < 0 || bit > 7)
	return;

    int mask = INT_MAX;
    mask -= pow(2, bit);
    int value = this->getValue() & mask;
    this->setValue(value);
}


bool Register::isSet(int bit) const
{
    if (bit < 0 || bit > 7)
	return false;

    int mask = pow(2, bit);
    return (this->getValue() & mask) > 0;
}


void Register::setValue(int value, bool force)
{
    QMutexLocker locker(this->mutex);

    if (this->getValue() != (value & 255))
    {
	int old = this->getValue();

	this->value = value & 255;

	emit contentChanged(old);
	emit changed(this->address, this->bank);
    }
}


int Register::getValue() const
{
    QMutexLocker locker(this->mutex);
    return this->value;
}

const int Register::getBank() const
{
    return this->bank;
}

const int Register::getAddress() const
{
    return this->address;
}

void Register::clear()
{
    this->setValue(0);
}

void Register::reset()
{
    this->setValue(this->standard);
}


Register& Register::operator++(int)
{
    this->setValue(this->getValue() + 1);
    return *this;
}


Register& Register::operator--(int)
{
    this->setValue(this->getValue() - 1);
    return *this;
}


Register& Register::operator<<(int digits)
{
    this->setValue(this->getValue() << digits);
    return *this;
}


Register& Register::operator>>(int digits)
{
    this->setValue(this->getValue() >> digits);
    return *this;
}


Register& Register::operator+=(int value)
{
    this->setValue(this->getValue() + value);
    return *this;
}


Register& Register::operator-=(int value)
{
    this->setValue(this->getValue() - value);
    return *this;
}


Register& Register::operator&=(int value)
{
    this->setValue(this->getValue() & value);
    return *this;
}


Register& Register::operator|=(int value)
{
    this->setValue(this->getValue() | value);
    return *this;
}


Register& Register::operator^=(int value)
{
    this->setValue(this->getValue() ^ value);
    return *this;
}


bool Register::operator==(int value)
{
    return this->getValue() == value;
}


bool Register::operator==(Register &reg)
{
    return this->getValue() == reg.getValue();
}


Register& Register::operator+(int value)
{
    this->setValue(this->getValue() + value);
    return *this;
}


Register& Register::operator-(int value)
{
    this->setValue(this->getValue() - value);
    return *this;
}


Register& Register::operator&(int value)
{
    this->setValue(this->getValue() & value);
    return *this;
}


Register& Register::operator|(int value)
{
    this->setValue(this->getValue() | value);
    return *this;
}


Register& Register::operator^(int value)
{
    this->setValue(this->getValue() ^ value);
    return *this;
}


Register& Register::operator=(int value)
{
    this->setValue(value);
    return *this;
}


QString Register::toString(int bit) const
{
    QMutexLocker locker(this->mutex);
    if (bit < 0 || bit > 7)
    {
	QString ret = QString::number(this->getValue(), 16).toUpper();

	if (qAbs(this->value) < 16)
	    return "0" + ret;
	else
	    return ret;
    }

    int mask = pow(2, bit);
    return QString::number(this->getValue() & mask, 16);
}
